#include "stdafx.h"
#include "Utc.h"

#include <time.h>

TimeZone::Utc* TimeZone::Utc::m_instance = 0;

//--------------------------------------------------------------------------------
TimeZone::Utc::Utc(int source_tz_index)
	: m_source_bias(source_tz_index)
{
	_ASSERTE(!m_instance);
	m_instance = this;
}
//--------------------------------------------------------------------------------
TimeZone::Utc::~Utc(void)
{
	m_instance = 0;
}
//--------------------------------------------------------------------------------
/*
	1. Take current utc time.
	2. Take date part of current utc time (current_midnight_utc).
	3. Take tz bias at current utc time.
	4. Get result in utc.
	5. If result is much greater than current utc time, than subscract (24 * 60 * 60) seconds from it.
	6. If result is much lesser than current utc time, than add (24 * 60 * 60) seconds from it.
*/
int TimeZone::Utc::_fromSecondsFromMidnight(int seconds_from_midnight)
{
	static const int much = 23 * 60 * 60;
	// 1.
	const int current_utc = static_cast<int>(time(0));
	// 2.
	const int current_midnight_utc = current_utc - (current_utc % (24 * 60 * 60));
	// 3.
	const int bias = m_instance->m_source_bias.biasSeconds(current_utc);
	// 4.
	int result_utc = current_midnight_utc + seconds_from_midnight + bias;
	// 5.
	if (result_utc - current_utc > much)
	{
		result_utc -= 24 * 60 * 60;
	}
	// 6.
	else if (current_utc - result_utc > much)
	{
		result_utc += 24 * 60 * 60;
	}
	//
	return result_utc;
}
//--------------------------------------------------------------------------------
int TimeZone::Utc::fromSecondsFromMidnight(int seconds_from_midnight)
{
	_ASSERTE(m_instance); // _ASSERTE is faster than Q_ASSERT.

	return m_instance->_fromSecondsFromMidnight(seconds_from_midnight);
}
